using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using FireStarter.Base;
using Habanero.Base;
using FireStarterModeller.BO;
using Habanero.BO.ClassDefinition;

namespace FireStarterModeller.Logic.ClassDefExport
{
    public static class XmlWriterClassDMs
    {
        public static string CreateClassDMXml(DMSolution dmSolution)
        {
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml("<classes />");

            XmlElement lXmlElementDMs = xmldoc.DocumentElement;
            foreach (DMClass classDM in dmSolution.AllClasses)
            {

                createClassDMXml(classDM, lXmlElementDMs);
            }

            return xmldoc.OuterXml;
        }

        private static void createClassDMXml(IClassDef classDef, XmlElement parentElement)
        {
            XmlElement classDMElement = XmlUtilities.createXmlElement(parentElement, "class");
            XmlUtilities.setXmlAttribute(classDMElement, "name", classDef.ClassName);
            XmlUtilities.setXmlAttribute(classDMElement, "assembly", classDef.AssemblyName);
            XmlUtilities.setXmlAttribute(classDMElement, "table", classDef.TableName, classDef.ClassName);
            XmlUtilities.setXmlAttribute(classDMElement, "displayName", classDef.DisplayName); //, DMClass.GetDisplayNameFromClassName(classDef.ClassName));

            createSuperClassDMXml(classDMElement, classDef);

            foreach (IPropDef propDef in classDef.PropDefcol)
            {
                createPropertyDMXml(classDMElement, propDef);
            }

            createKeyDMXml(classDMElement, classDef);

            createPrimaryKeyXml(classDMElement,classDef);

            foreach (IRelationshipDef relationshipDef in classDef.RelationshipDefCol)
            {
                createRelationshipXml(classDMElement, relationshipDef);
            }
            foreach (IUIDef uiDef in classDef.UIDefCol)
            {
                createUiXml(classDMElement, uiDef);
            }
        }


        private static void createSuperClassDMXml(XmlElement classDMElement, IClassDef DMClass)
        {
            ISuperClassDef superClassDef = DMClass.SuperClassDef;
            if (superClassDef == null) return;
            //if (!inheritanceRelationship.HasSuperClass) return;
            IClassDef superClassClassDef = superClassDef.SuperClassClassDef;
            if (superClassClassDef == null) return;
            XmlElement SuperClassDMElement = XmlUtilities.createXmlElement(classDMElement, "superClass");
            XmlUtilities.setXmlAttribute(SuperClassDMElement, "class", superClassClassDef.ClassName);
            XmlUtilities.setXmlAttribute(SuperClassDMElement, "assembly", superClassClassDef.AssemblyName);
            XmlUtilities.setXmlAttribute(SuperClassDMElement, "orMapping", superClassDef.ORMapping,
                                         ORMapping.ClassTableInheritance);
            switch (superClassDef.ORMapping)
            {
                case ORMapping.ClassTableInheritance:
                    XmlUtilities.setXmlAttribute(SuperClassDMElement, "discriminator", superClassDef.Discriminator, "");
                    XmlUtilities.setXmlAttribute(SuperClassDMElement, "id", superClassDef.ID, "");
                    break;
                case ORMapping.SingleTableInheritance:
                    XmlUtilities.setXmlAttribute(SuperClassDMElement, "discriminator", superClassDef.Discriminator, "");
                    break;
                case ORMapping.ConcreteTableInheritance:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private static void createPropertyDMXml(XmlElement classDMElement, IPropDef propDef)
        {
            XmlElement propDMElement = XmlUtilities.createXmlElement(classDMElement, "property");
            XmlUtilities.setXmlAttribute(propDMElement, "name", propDef.PropertyName);
            XmlUtilities.setXmlAttribute(propDMElement, "type", propDef.PropertyTypeName, "String");
            XmlUtilities.setXmlAttribute(propDMElement, "assembly", propDef.PropertyTypeAssemblyName, "System");
            XmlUtilities.setXmlAttribute(propDMElement, "readWriteRule", propDef.ReadWriteRule, PropReadWriteRule.ReadWrite );
            XmlUtilities.setXmlAttribute(propDMElement, "databaseField", propDef.DatabaseFieldName, propDef.PropertyName);
            XmlUtilities.setXmlAttribute(propDMElement, "default", propDef.DefaultValue);
            XmlUtilities.setXmlAttribute(propDMElement, "compulsory", propDef.Compulsory, false);
            XmlUtilities.setXmlAttribute(propDMElement, "autoIncrementing", propDef.AutoIncrementing, false);
            XmlUtilities.setXmlAttribute(propDMElement, "displayName", propDef.DisplayName, DMProperty.GetDisplayNameFromPropertyName(propDef.PropertyName));
            XmlUtilities.setXmlAttribute(propDMElement, "description", propDef.Description);
            XmlUtilities.setXmlAttribute(propDMElement, "keepValuePrivate", propDef.KeepValuePrivate, false);

            createPropRulesXml(propDMElement, propDef);
            createLookupListXml(propDMElement, propDef);
        }

        private static void createPropRulesXml(XmlElement propDMElement, IPropDef propDef)
        {
            foreach (IPropRule propRule in propDef.PropRules)
            {
                createPropRuleXml(propDMElement, propRule);
            }
        }

        private static void createPropRuleXml(XmlElement propDMElement, IPropRule propRule)
        {
            if (propRule == null) return;
            if (propRule.Name == null) return;
            if (propRule.Parameters.Count == 0) return;
            if (new List<object>(propRule.Parameters.Values).TrueForAll(o => o == null)) return;

            //if (!propRule.HasRule) return;
            XmlElement ruleElement = XmlUtilities.createXmlElement(propDMElement, "rule");
            XmlUtilities.setXmlAttribute(ruleElement, "name", propRule.Name);
            //TODO Mark 28 Sep 2009: Investigate what is needed to support custom rules
            //if (propRule.IsCustomRule)
            //{
            //    XmlUtilities.setXmlAttribute(ruleElement, "class", propRule.ClassName);
            //    XmlUtilities.setXmlAttribute(ruleElement, "assembly", propRule.AssemblyName);
            //}
            XmlUtilities.setXmlAttribute(ruleElement, "message", propRule.Message);
            foreach (KeyValuePair<string, object> pair in propRule.Parameters)
            {
                addKeyValuePair(ruleElement, pair.Key, pair.Value, null);
            }
        }

        private static void addKeyValuePair(XmlElement ruleElement, string key, object attributeValue, object attributeDefault)
        {
            string value = XmlUtilities.ObjectValueToString(attributeValue);
            string defaultValue = XmlUtilities.ObjectValueToString(attributeDefault);
            bool isDefault = (value == defaultValue);
            isDefault |= string.IsNullOrEmpty(value);
            if (ruleElement != null && !string.IsNullOrEmpty(key) && !isDefault)
            {
                XmlElement addElement = XmlUtilities.createXmlElement(ruleElement, "add");
                XmlUtilities.setXmlAttribute(addElement, "key", key);
                XmlUtilities.setXmlAttribute(addElement, "value", value);
            }
        }

        private static void createLookupListXml(XmlElement propDMElement, IPropDef propDef)
        {
            ILookupList lookupListBase = propDef.LookupList;
            if (lookupListBase == null) return;
            //IClassDef lookupClass = lookupList.LookupClass;
            XmlElement lookupElement;
            if (lookupListBase is ISimpleLookupList)
            {
                ISimpleLookupList lookupList = (ISimpleLookupList) lookupListBase;

                lookupElement = XmlUtilities.createXmlElement(propDMElement, "simpleLookupList");
                foreach (KeyValuePair<string, string> pair in lookupList.GetLookupList())
                {
                    XmlElement addElement = XmlUtilities.createXmlElement(lookupElement, "item");
                    XmlUtilities.setXmlAttribute(addElement, "display", pair.Key);
                    XmlUtilities.setXmlAttribute(addElement, "value", pair.Value);
                }
            }

            if (lookupListBase is IDatabaseLookupList)
            {
                IDatabaseLookupList lookupList = (IDatabaseLookupList) lookupListBase;
                lookupElement = XmlUtilities.createXmlElement(propDMElement, "databaseLookupList");
                XmlUtilities.setXmlAttribute(lookupElement, "sql", lookupList.SqlString);
                XmlUtilities.setXmlAttribute(lookupElement, "timeout", lookupList.TimeOut, 10000);
                XmlUtilities.setXmlAttribute(lookupElement, "class", lookupList.ClassName);
                XmlUtilities.setXmlAttribute(lookupElement, "assembly", lookupList.AssemblyName);
            }

            if (lookupListBase is IBusinessObjectLookupList)
            {
                IBusinessObjectLookupList lookupList = (IBusinessObjectLookupList) lookupListBase;
                lookupElement = XmlUtilities.createXmlElement(propDMElement, "businessObjectLookupList");
                XmlUtilities.setXmlAttribute(lookupElement, "class", lookupList.ClassName);
                XmlUtilities.setXmlAttribute(lookupElement, "assembly", lookupList.AssemblyName);
                XmlUtilities.setXmlAttribute(lookupElement, "criteria", lookupList.CriteriaString);
                XmlUtilities.setXmlAttribute(lookupElement, "timeout", lookupList.TimeOut, 10000);
                //TODO Mark 28 Sep 2009: Check that this sort string is getting built correctly
                XmlUtilities.setXmlAttribute(lookupElement, "sort", lookupList.SortString);
            }
        }

        private static void createKeyDMXml(XmlElement classDMElement, IClassDef classDef)
        {
            foreach (IKeyDef keyDef in classDef.KeysCol)
            {
                XmlElement keyDMElement = XmlUtilities.createXmlElement(classDMElement, "key");
                string keyName = keyDef.KeyName;
                XmlUtilities.setXmlAttribute(keyDMElement, "name", keyName);
                XmlUtilities.setXmlAttribute(keyDMElement, "message", keyDef.Message);
                XmlUtilities.setXmlAttribute(keyDMElement, "ignoreIfNull", keyDef.IgnoreIfNull, false);

                foreach (IPropDef propDef in keyDef)
                {
                    XmlElement keyPropElement = XmlUtilities.createXmlElement(keyDMElement, "prop");
                    string propName = propDef.PropertyName;
                    //keyName = keyName.Replace(propName, "");
                    XmlUtilities.setXmlAttribute(keyPropElement, "name", propName);
                }
                keyName = keyName.Replace("_", "");
                if (keyName.Length == 0) 
                    keyDMElement.RemoveAttribute("name");
            }
        }

        private static void createPrimaryKeyXml(XmlElement classDMElement , IClassDef classDef)
        {

            IPrimaryKeyDef primaryKeyDef = classDef.PrimaryKeyDef;
            if (primaryKeyDef == null)
            {
                return;
            }

            if (primaryKeyDef.Count == 0) return;
            XmlElement primaryKeyDMElement = XmlUtilities.createXmlElement(classDMElement, "primaryKey");
            XmlUtilities.setXmlAttribute(primaryKeyDMElement,"isObjectID", primaryKeyDef.IsGuidObjectID, true);
            foreach (IPropDef dmKeyProperty in primaryKeyDef)
            {
                XmlElement keyPropElement = XmlUtilities.createXmlElement(primaryKeyDMElement, "prop");
                XmlUtilities.setXmlAttribute(keyPropElement, "name", dmKeyProperty.PropertyName);
            }
        }

        private static void createRelationshipXml(XmlElement classDMElement, IRelationshipDef relationshipDef)
        {
            //IClassDef relatedClassDef = relationshipDef.RelatedObjectClassDef;//.MyRelatedClass.CurrentClass;
            //if (relatedClassDef == null) return;
            XmlElement relationshipDMElement = XmlUtilities.createXmlElement(classDMElement, "relationship");
            XmlUtilities.setXmlAttribute(relationshipDMElement, "name", relationshipDef.RelationshipName);
            bool isMultiple = false;
            //TODO Mark 28 Sep 2009: Review this and change it to use the IRelationshipDef interface methods or classes
            DMRelationship dmRelationship = (DMRelationship) relationshipDef;
            if (dmRelationship.Cardinality == Cardinality.Single)
                XmlUtilities.setXmlAttribute(relationshipDMElement, "type", "single");
            else if (dmRelationship.Cardinality == Cardinality.Multiple)
            {
                XmlUtilities.setXmlAttribute(relationshipDMElement, "type", "multiple");
                isMultiple = true;
            }
            if (isMultiple)
            {
                XmlUtilities.setXmlAttribute(relationshipDMElement, "timeout", relationshipDef.TimeOut, 0);
            }
            XmlUtilities.setXmlAttribute(relationshipDMElement, "relatedClass", relationshipDef.RelatedObjectClassName);
            XmlUtilities.setXmlAttribute(relationshipDMElement, "reverseRelationship", relationshipDef.ReverseRelationshipName);
            XmlUtilities.setXmlAttribute(relationshipDMElement, "relatedAssembly", relationshipDef.RelatedObjectAssemblyName);
            XmlUtilities.setXmlAttribute(relationshipDMElement, "keepReference", relationshipDef.KeepReferenceToRelatedObject, true);
            XmlUtilities.setXmlAttribute(relationshipDMElement, "deleteAction", relationshipDef.DeleteParentAction, DeleteParentAction.Prevent);
            XmlUtilities.setXmlAttribute(relationshipDMElement, "relationshipType", relationshipDef.RelationshipType, RelationshipType.Association);
            if (isMultiple)
            {
                XmlUtilities.setXmlAttribute(relationshipDMElement, "orderBy", relationshipDef.OrderCriteriaString);
            } else
            {
                XmlUtilities.setXmlAttribute(relationshipDMElement, "owningBOHasForeignKey", relationshipDef.OwningBOHasForeignKey, true);
            }

            foreach (IRelPropDef relPropDef in relationshipDef.RelKeyDef)
            {
                if (relPropDef.OwnerPropertyName != null && relPropDef.RelatedClassPropName != null)
                {
                    XmlElement relPropElement = XmlUtilities.createXmlElement(relationshipDMElement, "relatedProperty");
                    XmlUtilities.setXmlAttribute(relPropElement, "property", relPropDef.OwnerPropertyName);
                    XmlUtilities.setXmlAttribute(relPropElement, "relatedProperty", relPropDef.RelatedClassPropName);
                }
            }
            classDMElement.AppendChild(relationshipDMElement);
        }

        private static void createUiXml(XmlElement classDMElement, IUIDef uiDef)
        {
            XmlElement uiDMElement = XmlUtilities.createXmlElement(classDMElement, "ui");
            XmlUtilities.setXmlAttribute(uiDMElement, "name", uiDef.Name, "default");
            createUiGridXml(uiDMElement, uiDef.UIGrid);
            createUiFormXml(uiDMElement, uiDef.UIForm);
        }

        private static void createUiGridXml(XmlElement uiDMElement, IUIGrid uiGrid)
        {
            if (uiGrid == null) return;
            if (uiGrid.Count == 0) return;
            XmlElement uiGridDMElement = XmlUtilities.createXmlElement(uiDMElement, "grid");
            XmlUtilities.setXmlAttribute(uiGridDMElement, "sortColumn", uiGrid.SortColumn);
            createUiGridFilterXml(uiGridDMElement, uiGrid.FilterDef);
            foreach (IUIGridColumn uiGridColumn in uiGrid)
            {
                createUiGridColumnXml(uiGridDMElement, uiGridColumn);
            }
        }

        private static void createUiGridFilterXml(XmlElement uiGridDMElement, IFilterDef filterDef)
        {
            if (filterDef == null) return;
            XmlElement uiGridFilterElement = XmlUtilities.createXmlElement(uiGridDMElement, "filter");
            XmlUtilities.setXmlAttribute(uiGridFilterElement, "filterMode", filterDef.FilterMode, FilterModes.Filter);
            foreach (IFilterPropertyDef filterPropertyDef in filterDef.FilterPropertyDefs)
            {
                createUiGridFilterPropertyXml(uiGridFilterElement, filterPropertyDef);
            }
        }

        private static void createUiGridFilterPropertyXml(XmlElement uiGridFilterElement, IFilterPropertyDef filterPropertyDef)
        {
            XmlElement uiGridFilterPropertyElement = XmlUtilities.createXmlElement(uiGridFilterElement, "filterProperty");
            XmlUtilities.setXmlAttribute(uiGridFilterPropertyElement, "name", filterPropertyDef.PropertyName);
            XmlUtilities.setXmlAttribute(uiGridFilterPropertyElement, "label", filterPropertyDef.Label);
            XmlUtilities.setXmlAttribute(uiGridFilterPropertyElement, "filterType", filterPropertyDef.FilterType, "StringTextBoxFilter");
            XmlUtilities.setXmlAttribute(uiGridFilterPropertyElement, "filterTypeAssembly", filterPropertyDef.FilterTypeAssembly, BOBroker.GetMapperAssemblyName());
            XmlUtilities.setXmlAttribute(uiGridFilterPropertyElement, "operator", filterPropertyDef.FilterClauseOperator, FilterClauseOperator.OpLike);
        }


        private static void createUiGridColumnXml(XmlElement uiGridDMElement, IUIGridColumn uiGridColumn)
        {
            //DMProperty dmProperty = uiGridColumn.Property;
            XmlElement uiGridPropertyDMElement = XmlUtilities.createXmlElement(uiGridDMElement, "column");
            XmlUtilities.setXmlAttribute(uiGridPropertyDMElement, "heading", uiGridColumn.Heading);
                //, uiGridColumn.ConstructedHeading);
            XmlUtilities.setXmlAttribute(uiGridPropertyDMElement, "property", uiGridColumn.PropertyName);
            XmlUtilities.setXmlAttribute(uiGridPropertyDMElement, "type", uiGridColumn.GridControlTypeName, "DataGridViewTextBoxColumn");
            XmlUtilities.setXmlAttribute(uiGridPropertyDMElement, "assembly", uiGridColumn.GridControlAssemblyName, "System.Windows.Forms", "Habanero.Faces");
            XmlUtilities.setXmlAttribute(uiGridPropertyDMElement, "editable", uiGridColumn.Editable, true);
            XmlUtilities.setXmlAttribute(uiGridPropertyDMElement, "width", uiGridColumn.Width, 100);
            XmlUtilities.setXmlAttribute(uiGridPropertyDMElement, "alignment", uiGridColumn.Alignment, PropAlignment.left);
            foreach (DictionaryEntry parameter in uiGridColumn.Parameters)
            {
                createUiGridColumnParameterXml(uiGridPropertyDMElement, parameter);
            }
        }

        private static void createUiGridColumnParameterXml(XmlElement uiGridPropertyDMElement, DictionaryEntry keyValuePair)
        {
            string key = Convert.ToString(keyValuePair.Key);
            if (String.IsNullOrEmpty(key)) return;
            XmlElement uiFormFieldParamDMElement = XmlUtilities.createXmlElement(uiGridPropertyDMElement, "parameter");
            XmlUtilities.setXmlAttribute(uiFormFieldParamDMElement, "name", key);
            XmlUtilities.setXmlAttribute(uiFormFieldParamDMElement, "value", Convert.ToString(keyValuePair.Value));
        }

        private static void createUiFormXml(XmlElement uiDMElement, IUIForm uiForm)
        {
            if (uiForm == null) return;
            XmlElement uiFormDMElement = XmlUtilities.createXmlElement(uiDMElement, "form");
            XmlUtilities.setXmlAttribute(uiFormDMElement, "title", uiForm.Title);
            XmlUtilities.setXmlAttribute(uiFormDMElement, "width", uiForm.Width, 300, -1);
            XmlUtilities.setXmlAttribute(uiFormDMElement, "height", uiForm.Height, 250, -1);
            bool success = createUiFormTabsXml(uiFormDMElement, uiForm);
            if (!success)
            {
                uiDMElement.RemoveChild(uiFormDMElement);
            }
        }

        private static bool createUiFormTabsXml(XmlElement uiFormDMElement, IUIForm uiForm)
        {
            bool success = false;
            if (uiForm.Count == 0) return false;
            if (uiForm.Count > 1)
            {
                foreach (IUIFormTab dmUiFormTab in uiForm)
                {
                    XmlElement uiFormTabDMElement = XmlUtilities.createXmlElement(uiFormDMElement, "tab");
                    XmlUtilities.setXmlAttribute(uiFormTabDMElement, "name", dmUiFormTab.Name);
                    success |= createUiFromColumnsXml(uiFormTabDMElement, dmUiFormTab);
                }
            } else
            {
                IUIFormTab dmUiFormTab = uiForm[0];
                success |= createUiFromColumnsXml(uiFormDMElement, dmUiFormTab);
            }
            return success;
        }

        private static bool createUiFromColumnsXml(XmlElement parentElement, IUIFormTab uiFormTab)
        {
            bool success = false;
            if (uiFormTab.Count == 0) return false;
            if (uiFormTab.Count > 1)
            {
                foreach (IUIFormColumn dmUiFormColumn in uiFormTab)
                {
                    success |= createUiFormColumnXml(parentElement, dmUiFormColumn);
                }
            } else
            {
                IUIFormColumn dmUiFormColumn = uiFormTab[0];
                if (dmUiFormColumn.Width > 0)
                {
                    success |= createUiFormColumnXml(parentElement, dmUiFormColumn);
                } else
                {
                    success |= createUiFormFieldsXml(parentElement, dmUiFormColumn);
                }
            }
            return success;
        }

        private static bool createUiFormColumnXml(XmlElement parentElement, IUIFormColumn uiFormColumn)
        {
            XmlElement uiFormColumnDMElement = XmlUtilities.createXmlElement(parentElement, "columnLayout");
            XmlUtilities.setXmlAttribute(uiFormColumnDMElement, "width", uiFormColumn.Width, -1);
            return createUiFormFieldsXml(uiFormColumnDMElement, uiFormColumn);
        }

        private static bool createUiFormFieldsXml(XmlElement parentElement, IUIFormColumn uiFormColumn)
        {
            bool success = false;
            if (uiFormColumn.Count == 0) return false;
            foreach (IUIFormField dmUiFormField in uiFormColumn)
            {
                XmlElement uiFormFieldDMElement = XmlUtilities.createXmlElement(parentElement, "field");
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "label", dmUiFormField.Label); //, dmUiFormField.ConstructedLabel);

                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "property", dmUiFormField.PropertyName);
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "type", dmUiFormField.ControlTypeName, "TextBox");
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "assembly", dmUiFormField.ControlAssemblyName, "System.Windows.Forms");

                //TODO Mark 28 Sep 2009: Check how the automatic types will be populated.
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "mapperType", dmUiFormField.MapperTypeName);//,Global.DefaultControlMapperType);
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "mapperAssembly", dmUiFormField.MapperAssembly,
                                                 "Habanero.Faces", "Habanero.Faces.Forms");
                //string defaultToolTipText = "";
                //if (dmProperty != null)
                //{
                //    defaultToolTipText = dmProperty.PropDescription;
                //}
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "editable", dmUiFormField.Editable, true);
                if (dmUiFormField.ShowAsCompulsory.GetValueOrDefault())
                    XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "showAsCompulsory", dmUiFormField.ShowAsCompulsory);
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "toolTipText", dmUiFormField.ToolTipText);//,defaultToolTipText);
                XmlUtilities.setXmlAttribute(uiFormFieldDMElement, "layout", dmUiFormField.Layout);//,defaultToolTipText);
                foreach (DictionaryEntry keyValuePair in dmUiFormField.Parameters)
                {
                    createUiFormFieldParameterXml(uiFormFieldDMElement, keyValuePair);
                }
                success = true;
            }
            return success;
        }

        private static void createUiFormFieldParameterXml(XmlElement uiFormFieldDMElement, DictionaryEntry keyValuePair)
        {
            string key = Convert.ToString(keyValuePair.Key);
            if (String.IsNullOrEmpty(key)) return;
            XmlElement uiFormFieldParamDMElement = XmlUtilities.createXmlElement(uiFormFieldDMElement, "parameter");
            XmlUtilities.setXmlAttribute(uiFormFieldParamDMElement, "name", key);
            XmlUtilities.setXmlAttribute(uiFormFieldParamDMElement, "value", Convert.ToString(keyValuePair.Value));
        }

        #region Utility Methods

        //gets text out of a single node
        //returns true if the node was found and the result is returned in the strResult

        #endregion Utility Methods

    }
}